package com.lagou.lesson2.core.context;

import com.lagou.lesson2.core.annotation.Autowired;
import com.lagou.lesson2.core.annotation.Service;
import com.lagou.lesson2.core.config.XMLBeanConfigParser;
import com.lagou.lesson2.factory.BeanFactory;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.LinkedHashSet;
import java.util.Set;

public class ClassPathApplicationContext {

    private static ClassPathApplicationContext context = new ClassPathApplicationContext();
    // 私有化构造器
    private ClassPathApplicationContext() {

    }

    public static ClassPathApplicationContext getInstance() {
        // 构造器中初始化
        return context;
    }

    public void initApplicationContext(String configFile) {
        try {
            InputStream inputStream = XMLBeanConfigParser.class.getClassLoader().getResourceAsStream(configFile);
            Set<String> packages = XMLBeanConfigParser.parseBeanScanner(inputStream);

            Set<Class> annotatedClass = new LinkedHashSet<>();
            // 扫描包下加了注解的类，并将相关信息放入 beanDefinitionMap
            for (String aPackage : packages) {
                Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(aPackage);
                // 扫描 @Service 注解的类
                if(clazz.isAnnotationPresent(Service.class)) {
                    String beanId = clazz.getSimpleName();
                    Service annotation = clazz.getAnnotation(Service.class);
                    String beanname = BeanFactory.getInstance().getBeanName(annotation.value(), beanId);
                    BeanFactory.beanDefinitionMap.put(beanname, clazz);
                    annotatedClass.add(clazz);
                }
            }
            // 开始为扫描到的类创建对象
            for (Class aClass : annotatedClass) {
                Service annotation = (Service) aClass.getAnnotation(Service.class);
                String beanname = BeanFactory.getInstance().getBeanName(annotation.value(), aClass.getSimpleName());
                BeanFactory.getInstance().createBean(aClass.getName(), beanname);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Object getBean(String beanId) {
        return BeanFactory.getInstance().getBean(beanId);
    }
}
